home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include "mgP.h"
- #include "mgglP.h"
- #include "windowP.h"
- #include "mgglshade.h"
- #include <gl/gl.h>
- #include <stdio.h>
-
- mgcontext * mggl_ctxcreate(int a1, ...);
- void mggl_ctxset( int a1, ... );
- int mggl_feature( int feature );
- void mggl_ctxdelete( mgcontext *ctx );
- int mggl_ctxget( int attr, void* valueptr );
- int mggl_ctxselect( mgcontext *ctx );
- void mggl_sync( void );
- void mggl_worldbegin( void );
- void mggl_worldend( void );
- void mggl_reshapeviewport( void );
- void mggl_identity( void );
- void mggl_transform( Transform T );
- int mggl_pushtransform( void );
- int mggl_poptransform( void );
- void mggl_gettransform( Transform T );
- void mggl_settransform( Transform T );
- int mggl_pushappearance( void );
- int mggl_popappearance( void );
- Appearance *mggl_setappearance( Appearance* app, int merge );
- Appearance *mggl_getappearance( void );
- int mggl_setcamera( Camera* cam );
- int mggl_setwindow( WnWindow *win, int final );
- mgglcontext *mggl_newcontext( mgglcontext *ctx );
-
- extern void mggl_polygon();
- extern void mggl_mesh();
- extern void mggl_line();
- extern void mggl_polyline();
- extern void mggl_polylist();
- extern void mggl_quads();
-
-
-
- void _mggl_ctxset(int a1, va_list *alist);
-
- WnWindow *mgglwindow(WnWindow *win);
-
- static unsigned long PackColorA(ColorA *c);
-
- struct mgfuncs mgglfuncs = {
- MGD_GL,
- mgdevice_GL,
- mggl_feature,
- (mgcontext *(*)())mggl_ctxcreate,
- mggl_ctxdelete,
- (void (*)())mggl_ctxset,
- mggl_ctxget,
- mggl_ctxselect,
- mggl_sync,
- mggl_worldbegin,
- mggl_worldend,
- mggl_reshapeviewport,
- mggl_settransform,
- mggl_gettransform,
- mggl_identity,
- mggl_transform,
- mggl_pushtransform,
- mggl_poptransform,
- mggl_pushappearance,
- mggl_popappearance,
- mggl_setappearance,
- mggl_getappearance,
- mggl_setcamera,
- mggl_polygon,
- mggl_polylist,
- mggl_mesh,
- mggl_line,
- mggl_polyline,
- mggl_quads,
- mg_bezier
- };
-
- int
- mgdevice_GL()
- {
- _mgf = mgglfuncs;
- if (_mgc != NULL && _mgc->devno != MGD_GL)
- _mgc = NULL;
- return(0);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_ctxcreate
- * Date: Thu Jul 18 18:55:18 1991
- * Author: mbp
- * Notes: see mg.doc for rest of spec
- */
- mgcontext *
- mggl_ctxcreate(int a1, ...)
- {
- va_list alist;
-
-
- _mgc =
- (mgcontext*)mggl_newcontext( OOGLNewE(mgglcontext, "mggl_ctxcreate") );
-
- va_start(alist, a1);
- _mggl_ctxset(a1, &alist);
- va_end(alist);
- return _mgc;
- }
-
- /*-----------------------------------------------------------------------
- * Function: _mggl_ctxset
- * Description: internal ctxset routine
- * Args: a1: first attribute
- * *alist: rest of attribute-value list
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 11:08:13 1991
- * Notes: mggl_ctxcreate() and mggl_ctxset() call this to actually
- * parse and interpret the attribute list.
- */
- void
- _mggl_ctxset(int a1, va_list *alist)
- {
- int attr;
- WnWindow *owin;
- char **ablock = NULL;
-
- #define NEXT(type) OOGL_VA_ARG(type,alist,ablock)
-
- for (attr = a1; attr != MG_END; attr = NEXT(int)) {
- switch (attr) {
- case MG_ABLOCK:
- ablock = NEXT(char**);
- break;
- case MG_ApSet:
- {
- Appearance *ap;
-
- if (ablock) {
- ap = ApSet(NULL, AP_ABLOCK, ablock);
- } else {
- ap = _ApSet(NULL, va_arg(*alist, int), alist);
- }
-
- mggl_setappearance(ap, MG_MERGE);
- ApDelete(ap);
- }
- break;
- case MG_WnSet:
- if (ablock) {
- WnSet( _mgc->win, WN_ABLOCK, ablock);
- } else {
- _WnSet( _mgc->win, va_arg(*alist, int), alist);
- }
- mggl_setwindow( _mgc->win, 0 );
- break;
- case MG_CamSet:
- if (ablock) {
- CamSet( _mgc->cam, CAM_ABLOCK, ablock);
- } else {
- _CamSet( _mgc->cam, va_arg(*alist, int), alist); break;
- }
- case MG_APPEAR: mgsetappearance(NEXT(Appearance *), MG_SET);
- break;
- case MG_WINDOW: mggl_setwindow( NEXT(WnWindow *), 0 ); break;
- case MG_CAMERA: mggl_setcamera( NEXT(Camera*) ); break;
- case MG_SETOPTIONS: _mgc->opts |= NEXT(int); break;
- case MG_UNSETOPTIONS: _mgc->opts &= ~NEXT(int); break;
- case MG_SHOW: _mgc->shown = NEXT(int); break;
- case MG_PARENT: _mgc->parent = NEXT(mgcontext*); break;
- case MG_BACKGROUND: _mgc->background = *NEXT(ColorA*); break;
-
- case MG_SHADER: mggl_setshader( NEXT(mgshadefunc) ); break;
- case MG_SHADERDATA: _mgc->astk->shaderdata = NEXT(void*); break;
-
- case MG_SPACE:
- {
- int space = NEXT(int);
- switch (TM_SPACE(space)) {
- case TM_EUCLIDEAN:
- case TM_SPHERICAL:
- _mgc->space = space;
- break;
- case TM_HYPERBOLIC:
- switch (TM_MODEL(space)) {
- case TM_VIRTUAL:
- case TM_PROJECTIVE:
- case TM_CONFORMAL_BALL:
- _mgc->space = space;
- break;
- default:
- fprintf(stderr, "_mggl_ctxset: Illegal space value %1d\n", space);
- break;
- }
- break;
- default:
- fprintf(stderr, "_mggl_ctxset: Illegal space value %1d\n", space);
- break;
- }
- }
- break;
-
- case MG_NDINFO: _mgc->NDinfo = NEXT(void *); break;
- case MG_NDMAP: _mgc->NDmap = NEXT(mgmapfunc); break;
-
- /* GL-specific */
- case MG_ZNUDGE:
- _mgc->zfnudge = NEXT(double);
- if(_mgglc->born) mggl_init_zrange();
- break;
-
- case MG_GLWINID:
- _mgglc->win = NEXT(int);
- break;
-
- case MG_GLXDISPLAY:
- _mgglc->GLXdisplay = NEXT(void *);
- break;
-
- default:
- OOGLError (0, "_mggl_ctxset: undefined option: %d", attr);
- return;
- }
- }
-
- if (_mgc->shown && !_mgglc->born) {
-
- /* open the window */
- mgglwindow(_mgc->win);
-
- /* bring gl state into accordance with appearance state */
- {
- Appearance *ap = ApCopy( &(_mgc->astk->ap), NULL );
- mggl_setappearance( ap, MG_SET );
- ApDelete(ap);
- }
-
- }
-
- #undef NEXT
-
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_ctxget
- * Description: get a context attribute value
- * Args: attr: the attribute to get
- * value: place to write attr's value
- * Returns: 1 for success; -1 if attr is invalid
- * Author: mbp
- * Date: Fri Sep 20 11:50:25 1991
- * Notes:
- */
- int
- mggl_ctxget(int attr, void* value)
- {
- #define VALUE(type) ((type*)value)
-
- switch (attr) {
-
- /* Attributes common to all MG contexts: */
- case MG_APPEAR: *VALUE(Appearance*) = &(_mgc->astk->ap); break;
- case MG_CAMERA: *VALUE(Camera*) = _mgc->cam; break;
- case MG_WINDOW:
- if(_mgglc->born) {
- long x0, y0, xsize, ysize;
- WnPosition wp;
- getorigin(&x0, &y0);
- getsize(&xsize, &ysize);
- wp.xmin = x0; wp.xmax = x0+xsize-1;
- wp.ymin = y0; wp.ymax = y0+ysize-1;
- WnSet(_mgc->win, WN_CURPOS, &wp, WN_END);
- }
- *VALUE(WnWindow*) = _mgc->win;
- break;
- case MG_PARENT: *VALUE(mgcontext*) = _mgc->parent; break;
-
- case MG_SETOPTIONS:
- case MG_UNSETOPTIONS: *VALUE(int) = _mgc->opts; break;
-
- case MG_BACKGROUND: *VALUE(ColorA) = _mgc->background; break;
-
- case MG_SHADER: *VALUE(mgshadefunc) = _mgc->astk->shader; break;
- case MG_SHADERDATA: *VALUE(void *) = _mgc->astk->shaderdata; break;
- case MG_SPACE: *VALUE(int) = _mgc->space; break;
- case MG_NDINFO: *VALUE(void *) = _mgc->NDinfo; break;
- case MG_NDMAP: *VALUE(mgmapfunc) = _mgc->NDmap; break;
-
- /* Attributes specific to GL contexts: */
- case MG_GLWINID: *VALUE(int) = _mgglc->win; break;
- case MG_GLBORN: *VALUE(int) = _mgglc->born; break;
- case MG_GLZMAX: *VALUE(long) = _mgglc->zmax; break;
- case MG_ZNUDGE: *VALUE(float) = _mgc->zfnudge; break;
-
- default:
- OOGLError (0, "mggl_ctxget: undefined option: %d", attr);
- return -1;
-
- }
- return 1;
-
- #undef VALUE
- }
-
- /*-----------------------------------------------------------------------
- * Function: mgglwindow
- * Description: create a GL window
- * Args: *win: the WnWindow structure to realize
- * Returns: win if success, NULL if not
- * Author: mbp, slevy
- * Date: Fri Sep 20 11:56:31 1991
- * Notes: makes the GL calls necessary to create a GL window
- * corresponding to *win. This involves the call to
- * winopen(), as well as various configuration things
- * like RGBmode(), zbuffer(), gconfig(), etc.
- */
- WnWindow *
- mgglwindow(WnWindow *win)
- {
- WnPosition pos;
- int xsize, ysize, flag;
- int zmin;
- char *name;
- char gver[80];
-
- mggl_setwindow(win, 1);
-
- RGBmode();
- zbuffer(TRUE);
- subpixel(TRUE);
-
- mmode(MPROJECTION);
- loadmatrix( TM_IDENTITY );
- mmode(MVIEWING);
-
- if(_mgglc->GLXdisplay == NULL) {
- if(_mgc->opts & MGO_DOUBLEBUFFER)
- doublebuffer();
- gconfig();
- }
- _mgglc->oldopts = _mgc->opts;
- _mgglc->born = 1;
- _mgglc->zmax = getgdesc(GD_ZMAX);
- _mgglc->zmin = getgdesc(GD_ZMIN);
- mggl_init_zrange();
-
- _mgglc->cantwoside = getgdesc(GD_LIGHTING_TWOSIDE);
-
- gversion(gver);
- _mgglc->is_PI = (strncmp(gver, "GL4DPI", 6) == 0);
- _mgglc->turbo = (strncmp(gver, "GL4DPIT", 7) == 0);
-
- czclear(PackColorA(&(_mgc->background)), _mgglc->zmax);
- if((_mgc->opts&MGO_DOUBLEBUFFER) && !(_mgc->opts&MGO_INHIBITSWAP) )
- swapbuffers();
-
- return(win);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_ctxset
- * Description: set some context attributes
- * Args: a1, ...: list of attribute-value pairs
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:00:18 1991
- */
- void mggl_ctxset( int a1, ... )
- {
- va_list alist;
-
- va_start( alist, a1 );
- _mggl_ctxset(a1, &alist);
- va_end(alist);
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_feature
- * Description: report whether the GL device has a particular feature
- * Args: feature: the feature to report on
- * Returns: an int giving info about feature
- * Author: mbp
- * Date: Fri Sep 20 12:00:58 1991
- * Notes: -1 means the feature is not present.
- *
- * NO OPTIONAL FEATURES SUPPORTED YET. ALWAYS RETURNS -1.
- */
- int mggl_feature( int feature )
- {
- return(-1);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_ctxdelete
- * Description: delete a GL context
- * Args: *ctx: context to delete
- * Returns: nothing
- * Author: slevy
- * Date: Tue Nov 12 10:29:04 CST 1991
- * Notes: Deleting the current context leaves the current-context
- * pointer set to NULL.
- */
- void mggl_ctxdelete( mgcontext *ctx )
- {
- if(ctx->devno != MGD_GL) {
- mgcontext *was = _mgc;
- mgctxselect(ctx);
- mgctxdelete(ctx);
- if(was != ctx)
- mgctxselect(was);
- } else {
- if(((mgglcontext *)ctx)->born)
- winclose(((mgglcontext *)ctx)->win);
- mg_ctxdelete(ctx);
- if(ctx == _mgc)
- _mgc = NULL;
- }
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_ctxselect
- * Description: select an MG context --- make it current
- * Args: *ctx: the context to become current
- * Returns: 0 (why ???)
- * Author: mbp
- * Date: Fri Sep 20 12:04:41 1991
- */
- int
- mggl_ctxselect( mgcontext *ctx )
- {
- if(ctx == NULL || ctx->devno != MGD_GL) {
- return mg_ctxselect(ctx);
- }
- /* Yes, it's a GL context. Do something useful. */
- _mgc = ctx;
- if(_mgglc->win) {
- if(_mgglc->GLXdisplay != NULL)
- GLXwinset(_mgglc->GLXdisplay, _mgglc->win);
- else
- winset(_mgglc->win);
- }
- return(0);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_sync
- * Description: flush buffered GL commands
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:06:09 1991
- * Notes: Just flushes the GL buffer -- needed for remote displays.
- */
- void
- mggl_sync( void )
- { gflush(); }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_worldbegin
- * Description: prepare to draw a frame
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:06:58 1991
- */
- void
- mggl_worldbegin( void )
- {
- Transform V, S;
-
- if((_mgglc->oldopts ^ _mgc->opts) & MGO_DOUBLEBUFFER) {
- if(_mgglc->GLXdisplay == NULL) {
- if(_mgc->opts & MGO_DOUBLEBUFFER) doublebuffer();
- else singlebuffer();
- gconfig();
- } else {
- OOGLError(1, "Note: Can't change single/doublebuffer config of GLX window");
- }
- _mgglc->oldopts = _mgc->opts;
- }
-
- RGBwritemask(_mgc->opts & MGO_NORED ? 0 : 255,
- _mgc->opts & MGO_NOGREEN ? 0 : 255,
- _mgc->opts & MGO_NOBLUE ? 0 : 255);
-
- /* Erase to background color & initialize z-buffer */
- if(_mgc->opts & MGO_INHIBITCLEAR) zclear();
- else czclear(PackColorA(&(_mgc->background)), _mgglc->zmax);
-
- mg_worldbegin(); /* Initialize W2C, C2W, W2S, S2W, etc. */
-
- _mgc->has = 0;
-
- /* Interpret the camera: load the proper matrices onto the GL matrix
- stacks. */
- if(!(_mgc->opts & MGO_INHIBITCAM)) {
- mmode(MPROJECTION);
- CamViewProjection( _mgc->cam, V );
- loadmatrix( V );
- mmode(MVIEWING);
- loadmatrix( _mgc->W2C );
- }
-
- /* Bind the lights; do this here so we get lights in world coords. */
- /* Only do this if we're supposed to do lighting */
-
- mg_globallights(_mgc->astk->lighting.lights, 1);
-
- if ( (_mgc->astk->lighting.lights != NULL) &&
- (_mgc->astk->ap.shading != APF_CONSTANT))
- mggl_lights(_mgc->astk->lighting.lights, _mgc->astk);
-
- /* Allow concave polygons. This could be an Appearance attribute. */
- concave(TRUE);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_worldend
- * Description: finish drawing a frame
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:08:02 1991
- */
- void
- mggl_worldend( void )
- {
- if((_mgc->opts&MGO_DOUBLEBUFFER) && !(_mgc->opts&MGO_INHIBITSWAP))
- swapbuffers();
- gflush();
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_reshapeviewport
- * Description: adjust to a new window size
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:08:30 1991
- * Notes: adjusts both GL's internal viewport setting, as well as
- * MG context WnWindow's current position and camera's
- * aspect ratio.
- */
- void
- mggl_reshapeviewport( void )
- {
- long w, h;
- float pixasp = 1;
- WnPosition vp;
-
- WnGet(_mgc->win, WN_PIXELASPECT, &pixasp);
- if(WnGet(_mgc->win, WN_VIEWPORT, &vp) <= 0) {
- getsize(&w, &h);
- reshapeviewport();
- } else {
- w = vp.xmax - vp.xmin + 1;
- h = vp.ymax - vp.ymin + 1;
- viewport(vp.xmin, vp.xmax, vp.ymin, vp.ymax);
- }
- CamSet(_mgc->cam, CAM_ASPECT, pixasp * (double)w/(double)h, CAM_END);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_identity
- * Description: set the current object xform to identity
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:23:48 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack.
- *
- * This assumes we're already in MVIEWING mode.
- */
- void
- mggl_identity( void )
- {
- /* [ obj xform ] = identity corresponds to having current W2C on
- ModelView stack */
- mggl_settransform( TM3_IDENTITY );
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_transform
- * Description: premultiply the object xform by T
- * Args: T
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:24:57 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack.
- *
- * This assumes we're already in MVIEWING mode.
- */
- void
- mggl_transform( Transform T )
- {
- multmatrix(T);
- TmConcat(T, _mgc->xstk->T, _mgc->xstk->T);
- _mgc->has = _mgc->xstk->hasinv = 0;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_pushtransform
- * Description: push the object xform stack
- * Returns: nothing (???)
- * Author: mbp
- * Date: Fri Sep 20 12:25:43 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack.
- *
- * This assumes we're already in MVIEWING mode.
- */
- int
- mggl_pushtransform( void )
- {
- pushmatrix();
- mg_pushtransform();
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_popransform
- * Description: pop the object xform stack
- * Returns: nothing (???)
- * Author: mbp
- * Date: Fri Sep 20 12:25:43 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack.
- *
- * This assumes we're already in MVIEWING mode.
- */
- mggl_poptransform( void )
- {
- popmatrix();
- mg_poptransform();
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_gettransform
- * Description: get the current object xform
- * Args: T: place to write the current object xform
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:29:43 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack. This means we must multiply on the right by
- * the current C2W matrix after reading the GL ModelView
- * matrix.
- *
- * This assumes we're already in MVIEWING mode.
- */
- void
- mggl_gettransform( Transform T )
- {
- TmCopy(_mgc->xstk->T, T);
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_settransform
- * Description: set the current object xform to T
- * Args: T
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:29:43 1991
- * Notes: We use the GL ModelView matrix stack, not the mgcontext's
- * stack. This means we must first load W2C onto the
- * modelview stact, then premult by T.
- *
- * This assumes we're already in MVIEWING mode.
- */
- void
- mggl_settransform( Transform T )
- {
- loadmatrix( _mgc->W2C );
- multmatrix( T );
- TmCopy(T, _mgc->xstk->T);
- _mgc->has = _mgc->xstk->hasinv = 0;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_pushappearance
- * Description: push the MG context appearance stack
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 12:54:19 1991
- */
- int
- mggl_pushappearance( void )
- {
- mg_pushappearance();
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_popappearance
- * Description: pop the MG context appearance stack
- * Returns: nothing
- * Author: mbp, munzner
- * Date: Fri Sep 20 12:54:19 1991
- * Note: We call mggl_lighting and mggl_material instead of
- * just doing lmbinds here because those procedures make the
- * proper existence checks and reset the GL drawing state.
- */
- int
- mggl_popappearance( void )
- {
- register struct mgastk *mastk = _mgc->astk;
- register struct mgastk *mastk_next;
-
- if (! (mastk_next=mastk->next)) {
- OOGLError(0, "mggl_popappearance: appearance stack has only 1 entry.");
- return;
- }
-
- if ((mastk->light_seq != mastk_next->light_seq) && /* changed */
- IS_SHADED(mastk->next->ap.shading)) /* lighting on */
- mggl_lighting(mastk_next, mastk_next->lighting.valid);
- mggl_appearance(mastk_next, mastk_next->ap.valid);
-
- mg_popappearance();
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_setappearance
- * Author: munzner, mbp
- * Date: Wed Aug 7 01:08:07 1991
- * Notes: when app=NULL, mergeflag = MG_MERGE is assumed
- * (regardless of the actual value of mergeflag).
- * In this case, we make the GL calls to bring
- * the GL state into agreement with the current
- * appearance.
- *
- * The above isn't true any more; update these comments
- * soon. -- mbp Mon Sep 23 19:07:39 1991
- *
- * things set here: material, lights, shading,
- * linewidth, transparency
- * things not set here: normals (drawing, scaling,
- * everting), drawing faces vs. edges
- */
- Appearance *
- mggl_setappearance( Appearance* ap, int mergeflag )
- {
- int changed, mat_changed, lng_changed;
- struct mgastk *mastk = _mgc->astk;
- Appearance *ma;
- static float nullarray[] = { LMNULL };
-
- ma = &(mastk->ap);
-
- /* Decide what changes */
- if (mergeflag == MG_MERGE) {
- changed = ap->valid &~ (ma->override &~ ap->override);
- mat_changed =
- ap->mat ? ap->mat->valid &~ (ma->mat->override &~ ap->mat->override) : 0;
- lng_changed =
- ap->lighting ? ap->lighting->valid &~
- (ma->lighting->override &~ ap->lighting->override) : 0;
- }
- else {
- changed = ap->valid;
- mat_changed = ap->mat ? ap->mat->valid : 0;
- lng_changed = ap->lighting ? ap->lighting->valid : 0;
- }
-
- /*
- * Update current appearance; this needs to be done before making GL
- * calls because it is conceivable that we might need to make a GL call
- * corresponding to something in the current appearance for which the
- * valid bit in *ap isn't set. (???) By updating the current
- * appearance before making GL calls, our GL calls can always take data
- * from the current appearance, rather than worrying about whether to
- * read *ap or the current appearance.
- */
- mg_setappearance( ap, mergeflag );
-
- /* Bring GL device into accord with new appearance */
- if (_mgglc->born) {
-
- /*
- * No bit in "changed" corresponds to {lighting,mat}. We think of
- * ap->{lighting,mat} as an extension to *ap which is interpreted to
- * have all valid bits 0 if the {lighting,ap} pointer is NULL. Note
- * that this means there is no way for the parent to override the
- * entire {lighting,mat} structure as a whole. It can, however, set
- * the individual override bits in the {lighting,mat} structure.
- */
- if ((ap->lighting) && (mastk->next)) {
- if (mastk->light_seq == mastk->next->light_seq) {
- mastk->light_seq++;
- /*
- * We need a new lighting model.
- * To ensure we don't have any leftover garbage in GL's copy of this
- * lighting model, we force GL to reset to defaults, then
- * reinitialize everything.
- */
- lmdef(DEFLMODEL, mastk->light_seq, 0, nullarray);
- lng_changed |= ma->lighting->valid; /* "All fields changed" */
- }
- }
- if (ma->shading != APF_CONSTANT && ap->lighting != NULL) {
- mggl_lighting( mastk, lng_changed );
- }
-
- /* Let mggl_material() decide if we need a new material */
- if (ap->mat)
- mggl_material( mastk, mat_changed );
-
- mggl_appearance( mastk, changed );
-
- }
-
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_getappearance
- * Description: return a ptr to current appearance
- * Returns: ptr to current appearance
- * Author: mbp
- * Date: Fri Sep 20 13:00:41 1991
- * Notes: Applications should not modify the returned appearance
- * in any way.
- */
- Appearance *
- mggl_getappearance()
- {
- return &(_mgc->astk->ap);
- }
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_setcamera
- * Description: set the context's camera (pointer)
- * Args: *cam: the camera to use
- * Returns: nothing
- * Author: mbp
- * Date: Fri Sep 20 13:07:31 1991
- * Notes: The context stores a pointer to the camera, not a copy
- * of it.
- */
- int
- mggl_setcamera( Camera* cam )
- {
- if (_mgc->cam) CamDelete(_mgc->cam);
- _mgc->cam = cam;
- RefIncr((Ref*) cam);
- }
-
- /*
- * Change current Window structure.
- * If 'final' and otherwise appropriate, actually open the window.
- * Apply relevant changes to window, if needed.
- */
- int
- mggl_setwindow( WnWindow *win, int final )
- {
- WnPosition pos, vp;
- int xsize, ysize, flag, reconstrain;
- int positioned = 0;
- int zmin;
- char *name, *oname;
-
- if(win == NULL)
- return 0;
-
- reconstrain = 0;
- if (WnGet(win, WN_PREFPOS, (void*)&pos) == 1 && (win->changed&WNF_HASPREF)) {
- if(_mgglc->born) {
- winposition(pos.xmin, pos.xmax, pos.ymin, pos.ymax);
- win->changed &= ~(WNF_HASPREF|WNF_HASSIZE);
- } else if(final) {
- prefposition(pos.xmin, pos.xmax, pos.ymin, pos.ymax);
- win->changed &= ~(WNF_HASPREF|WNF_HASSIZE);
- reconstrain = positioned = 1;
- }
- } else if ((WnGet(win, WN_XSIZE, (void*)&xsize) == 1
- && (WnGet(win, WN_YSIZE, (void*)&ysize) == 1
- && (win->changed&WNF_HASSIZE))) ) {
- prefsize(xsize, ysize);
- reconstrain = 1;
- win->changed &= ~WNF_HASSIZE;
- }
-
-
- if(reconstrain && _mgglc->born) {
- WnGet(win, WN_NOBORDER, &flag);
- if (flag) noborder();
- winconstraints();
- reconstrain = 0;
- }
-
- if(_mgc->shown) {
- WnGet(win, WN_NAME, &name);
- if(_mgglc->born) {
- if(name && (win->changed & WNF_HASNAME)) {
- wintitle(name);
- win->changed &= ~WNF_HASNAME;
- }
- if(WnGet(win, WN_VIEWPORT, &vp) > 0 && win->changed & WNF_HASVP) {
- viewport(vp.xmin, vp.xmax, vp.ymin, vp.ymax);
- win->changed &= ~WNF_HASVP;
- }
- } else if(final) {
- foreground();
- if(_mgglc->win <= 0)
- _mgglc->win = winopen(name);
- if(_mgglc->win == 0) {
- OOGLError(0,"mgglwindow: bad return from winopen: %s",sperror());
- return 0;
- }
- if(positioned) /* 4.0 kludge: ensure the window is where we want it! */
- winposition(pos.xmin, pos.xmax, pos.ymin, pos.ymax);
- _mgglc->born = 1;
- reconstrain = positioned;
- }
- }
-
- if((reconstrain && _mgglc->born)
- || (win->changed & (WNF_NOBORDER|WNF_ENLARGE|WNF_SHRINK))) {
- WnGet(win, WN_NOBORDER, &flag);
- if (flag) noborder();
-
- WnGet(win, WN_ENLARGE, &flag);
- if (flag) maxsize(getgdesc(GD_XPMAX), getgdesc(GD_YPMAX));
-
- WnGet(win, WN_SHRINK, &flag);
- if (flag) minsize((long)40, (long)30);
- reconstrain = 1;
- }
-
- if (reconstrain && _mgglc->born) {
- winconstraints();
- win->changed &= ~(WNF_NOBORDER | WNF_ENLARGE | WNF_SHRINK);
- }
-
- if(win != _mgc->win) {
- RefIncr((Ref *)win);
- WnDelete(_mgc->win);
- _mgc->win = win;
- }
- return 1;
- }
-
-
-
- /*-----------------------------------------------------------------------
- * Function: mggl_newcontext
- * Description: initialize a new mgglcontext structure
- * Args: *ctx: the struct to initialize
- * Returns: ctx
- * Author: mbp
- * Date: Fri Sep 20 13:11:03 1991
- */
- mgglcontext *
- mggl_newcontext( mgglcontext *ctx )
- {
- mg_newcontext(&(ctx->mgctx));
- ctx->mgctx.devfuncs = &mgglfuncs;
- ctx->mgctx.devno = MGD_GL;
- ctx->mgctx.astk->ap_seq = 1;
- ctx->mgctx.astk->mat_seq = 1;
- ctx->mgctx.astk->light_seq = 1;
- ctx->mgctx.zfnudge = 40.e-6;
- ctx->born = 0;
- ctx->win = 0;
- ctx->d4f = c4f;
- ctx->lmcolor = LMC_COLOR;
- ctx->n3f = n3f;
- VVINIT(ctx->room, char, 180);
- ctx->GLXdisplay = NULL;
- return ctx;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mggl_findctx
- * Description: Given a GL window ID, returns the associated mg context.
- * Returns: mgcontext * for success, NULL if none exists.
- * Author: slevy
- * Date: Mon Nov 11 18:33:53 CST 1991
- * Notes: This is a public routine.
- */
- mgcontext *
- mggl_findctx( int winid )
- {
- register struct mgcontext *mgc;
-
- for(mgc = _mgclist; mgc != NULL; mgc = mgc->next) {
- if(mgc->devno == MGD_GL && ((mgglcontext *)mgc)->win == winid)
- return mgc;
- }
- return NULL;
- }
-
- /*-----------------------------------------------------------------------
- * Function: PackColorA
- * Description: Pack a ColorA struct into an unsigned long int for
- * use by cpack() etc.
- * Args: *c: the ColorA to pack
- * Returns: the unsigned long corresponding to *c
- * Author: mbp
- * Date: Fri Sep 20 13:37:02 1991
- */
- static unsigned long
- PackColorA(ColorA *c)
- {
- unsigned long val,r,g,b,a;
-
- r = c->r * 255;
- g = c->g * 255;
- b = c->b * 255;
- a = c->a * 255;
-
- val = (a << 24) | (b << 16) | (g << 8) | r;
- return(val);
- }
-